package org.dna.metronomo.persistence.impl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.ibatis.session.SqlSession;
import org.dna.metronomo.persistence.IUserDAO;
import org.dna.metronomo.persistence.PersistenceException;
import org.dna.metronomo.persistence.User;
import org.dna.metronomo.persistence.UserMapper;

public class IBatisUserDAO extends IBatisMetronomoDAO implements IUserDAO {

    private final static Logger LOG = Logger.getLogger(IBatisUserDAO.class);

    public User findUser(final String username, final String password) {
        return executeInSession(new SessionExecutor<User>() {

            @SuppressWarnings("unchecked")
            public User execute(SqlSession session) {
                Map<String, String> param = new HashMap<String, String>();
                param.put("username", username);
                param.put("password", password);
                return (User) session.selectOne("org.dna.metronomo.persistence.UserMapper.selectByUserNamePwd", param);
            }
        });
    }

    public void addNewUser(final User user) {
        executeInSession(new SessionExecutor<Void>() {

            public Void execute(SqlSession session) {
                UserMapper mapper = session.getMapper(UserMapper.class);
                mapper.insert(user);
                return null;
            }
        });
    }

    public void update(final User user) {
        executeInSession(new SessionExecutor<Void>() {

            public Void execute(SqlSession session) {
                UserMapper mapper = session.getMapper(UserMapper.class);
                mapper.update(user);
                return null;
            }
        });
    }

    public List<User> users() {
        List<User>res = executeInSession(new SessionExecutor<List<User>>() {
            public List<User> execute(SqlSession session) {
                return (List<User>)session.selectList("org.dna.metronomo.persistence.UserMapper.allUsers");
            }
        });
        LOG.debug("users returned " + res);
        return res;
    }

    public void deleteByExample(final User... users) throws PersistenceException {
        executeInSession(new SessionExecutor<Void>() {

            public Void execute(SqlSession session) {
                for (User user : users) {
                    if (user.getJobs() == null || user.getJobs().isEmpty()) {
                        session.delete(
                                "org.dna.metronomo.persistence.UserMapper.deleteByExample",
                                user);
                    } else {
                        Map<String ,Object> param = new HashMap<String ,Object>();
                        param.put("user", user);
                        param.put("status", STATUS_DELETED);
                        session.update("org.dna.metronomo.persistence.UserMapper.updateStatusByExample", param);
                    }
                }
                return null;
            }
        });
    }

    public void deleteByID(final int... ids) throws PersistenceException {
        LOG.debug("deleting by IDs " + Arrays.toString(ids));
        executeInSession(new SessionExecutor<Void>() {

            public Void execute(SqlSession session) {
                for (int id : ids) {
                    User user = new QueryByIDExecutor(id).execute(session);
                    UserMapper mapper = session.getMapper(UserMapper.class);
                    if (user == null) {
                        continue;
                    }

                    if (user.getJobs() == null || user.getJobs().isEmpty()) {
                        mapper.deleteByID(id);
                    } else {
                        mapper.updateStatusByID(id, STATUS_DELETED);
                    }
                }
                return null;
            }
        });

    }

    private static class QueryByIDExecutor implements SessionExecutor<User> {

        int id;

        public QueryByIDExecutor(int id) {
            this.id = id;
        }

        @SuppressWarnings("unchecked")
        public User execute(SqlSession session) {
            User act = (User) session.selectOne(
                    "org.dna.metronomo.persistence.UserMapper.queryByID",
                    this.id);
            return act;
        }
    }

	public User findByID(int id) throws PersistenceException {
		// TODO Auto-generated method stub
		return null;
	}
}
